<script setup>
import { computed, onMounted, ref, watch } from 'vue'
import { JBoltApi } from '@/service/request'

const props = defineProps({
    url: String,
    options: {
        type: Array,
        default: () => []
    },
    labelField: {
        type: String,
        default: 'text'
    },
    valueField: {
        type: String,
        default: 'value'
    },
    valueToNumber: {
        type: Boolean,
        default: false
    },
    valueJoin: {
        type: [String, Boolean],
        default: ','
    },
    value: {
        type: [Array, String],
        default: undefined
    }
})

const emit = defineEmits(['update:value'])

const value = computed(() => {
    if (!props.value) return []
    if (Array.isArray(props.value)) {
        return [...props.value]
    }
    if (typeof props.value == 'string') {
        if (props.valueJoin === false) {
            throw new Error(
                '检测到jb-checkbox-group传入了一个字符串，valueJoin必须为有效的分割字符，否则组件无法解析'
            )
        }

        return props.value.split(props.valueJoin).map((v) => {
            if (props.valueToNumber) {
                return Number(v)
            }
            return v
        })
    }
    throw new Error('jb-checkbox-group不支持的value类型：' + props.value)
})

// 监听url变化，重新加载数据
watch([() => props.url, () => props.options], () => {
    loadOptions()
})

const loading = ref(false)
const dynamicOptions = ref([])

function processData(data = []) {
    data.forEach((item) => {
        let value = item[props.valueField]
        if (props.valueToNumber) {
            item[props.valueField] = Number(value)
        }
    })
    dynamicOptions.value = data
}

/**
 * 加载数据
 */
function loadOptions() {
    if (!props.url) {
        processData(props.options)
        return
    }
    loading.value = true

    JBoltApi.get(props.url, null, {
        ignoreMsg: true
    })
        .then(({ error, result }) => {
            if (error) {
                dynamicOptions.value = []
                return
            }
            if (result.data) {
                processData(result.data)
            }
        })
        .finally(() => {
            loading.value = false
        })
}

function onValueChange(v) {
    emit(
        'update:value',
        Array.isArray(props.value) || props.valueJoin === false
            ? v
            : v.join(props.valueJoin)
    )
}

onMounted(() => {
    loadOptions()
})

defineExpose({
    refresh: loadOptions
})
</script>

<template>
    <n-checkbox-group name="group" :value="value" @update:value="onValueChange">
        <n-space>
            <n-checkbox
                v-for="item in dynamicOptions"
                :key="item[props.valueField]"
                :value="
                    props.valueToNumber
                        ? Number(item[props.valueField])
                        : item[props.valueField]
                "
            >
                {{ item[props.labelField] }}
            </n-checkbox>
        </n-space>
    </n-checkbox-group>
</template>

<style scoped></style>
